<?php
/**
 * Cameo Library
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 *
 * @category   Cameo
 * @package    Cameo_SMS
 * @subpackage Gateway
 * @copyright  Copyright (c) 2008 Sylvain Filteau (http://www.cidsphere.com)
 */

/**
 * Cameo_SMS_Gateway_Abstract
 */
require_once('Cameo/SMS/Gateway/Abstract.php');

/**
 * Cameo_SMS_Gateway_Exception
 */
require_once('Cameo/SMS/Gateway/Exception.php');

/**
 * Zend_Http_Client
 */
require_once('Zend/Http/Client.php');

/**
 * Class that sends commands to the Clickatell gateway over HTTP.
 * 
 * Uses a Zend_Http_Client to sends command, so this class have a dependecy over
 * the Zend Framework library.
 * 
 * @todo describe the options for this gateway and options of the extended class
 * @todo implement commands that aren't sent over the standard uri
 *
 * @category   Cameo
 * @package    Cameo_SMS
 * @subpackage Gateway
 * @copyright  Copyright (c) 2008 Sylvain Filteau (http://www.cidsphere.com)
 */
class Cameo_SMS_Gateway_Clickatell_Http extends Cameo_SMS_Gateway_Clickatell {
	
	const OPT_USE_SSL = 'use_ssl';
	const OPT_HTTP_CLIENT = 'http_client';
	
	private $_api_url;
	
	private $_http_client;
	
	public function __construct(array $default_options = array()) {
		parent::__construct($default_options);
		
		if (isset($default_options[self::OPT_USE_SSL]) && $default_options[self::OPT_USE_SSL]) {
			$this->_api_url = 'https://api.clickatell.com/http/';
		} else {
			$this->_api_url = 'http://api.clickatell.com/http/';
		}
		
		if (isset($default_options[self::OPT_HTTP_CLIENT])) {
			$this->setHttpClient($default_options[self::OPT_HTTP_CLIENT]);
		} else {
			$this->setHttpClient(new Zend_Http_Client());
		}
	}
	
	public function setHttpClient(Zend_Http_Client $client) {
		$this->_http_client = $client;
	}
	
	protected function _callMethod($method, $params) {
		$valid_method = array(
			'sendmsg', 'auth', 'ping', 'querymsg', 'delmsg', 'getbalance', 
			/*'getmsgcharge', */'token_pay'/*, 'startbatch', 'senditem', 'quicksend', 'endbatch'*/
		);
		
		if (!in_array($method, $valid_method)) {
			throw new Cameo_SMS_Gateway_Exception('Cannot call the method "' . $method . '", it is invalid');
		}
		
		$url = $this->_api_url . $method;
		
		if ($method != 'ping') {
			$params = array_merge($params, $this->_getAuthParams());
		}
		
		$this->_http_client->setUri($url);
		$this->_http_client->setParameterPost($params);
		
		$response = $this->_http_client->request(Zend_Http_Client::POST);
		$body = $response->getBody();
		$status = $response->getStatus();
		
		if ($status != 200) {
			throw new Cameo_SMS_Gateway_Exception('Cannot successfully send the method "' . $method . '" to the '
												. 'gateway, the server respond with an invalid HTTP status "' 
												. $status . '". Body: "' . $body . '"');
		}
		
		if (substr($body, 0, 5) == 'ERR: ') {
			throw $this->_errorException(trim(substr($body, 5, 3)));
		}
		
		$ret = false;
		
		if ($method == 'sendmsg') {
			$ret = array();
			$lines = explode("\n", $body);
			
			foreach($lines as $line) {
				$to_pos = strpos($line, ' TO: ');
				$to_exist = true;
				if (false === $to_pos) {
					$to_exist = false;
					$to_pos = strlen($line);
				}
				
				$ret_line = array();
				
				$ret_line[Cameo_SMS_Gateway_Clickatell::OPT_API_MSG_ID] = trim(substr($line, 4, $to_pos - 4));
				if ($to_exist) {
					$ret_line['to'] = trim(substr($line, $to_pos + 5));
				} else {
					$ret_line['to'] = $params['to'];
				}
				
				$ret[] = $ret_line;
			}
		} elseif ($method == 'auth') {
			$this->_session_key = trim(substr($body, 4));
			$ret = $this->_session_key;
		} elseif (in_array($method, array('ping', 'token_pay'))) {
			$ret = true;
		} elseif (in_array($method, array('querymsg', 'delmsg'))) {
			$status_pos = strpos($body, ' Status: ');
			$ret = trim(substr($body, $status_pos + 9));
		} elseif ($method == 'getbalance') {
			$ret = floatval(trim(substr($body, 8)));
		}
		
		return $ret;
	}
}